package com.qcby.demo.web.exchange;

import cn.hutool.core.thread.ThreadFactoryBuilder;
import com.alibaba.fastjson.JSON;
import com.qcby.demo.base.dto.DemoDTO;
import com.qcby.demo.base.service.ITestService;
import com.qcby.framework.common.constants.NumberConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.util.concurrent.*;


/**
 * 自动交卷
 *
 * @author cong.zhen
 * @date 2023/04/11
 */
@Slf4j
@Component
public class AutoHandExchange {

    /**创建了一个线程池 */
    private static final ExecutorService ACCEPTED_DELAY_QUEUE_EXECUTOR = new ThreadPoolExecutor(1, 1,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(),
            ThreadFactoryBuilder.create().setNamePrefix("demo-autoHand-delay-queue-thread").build()
    );

    private static DelayQueue<DemoDTO> delayQueue = new DelayQueue();

    @Resource
    private ITestService testService;



    private static volatile boolean flag = false;

    /**
     * 触发新制作单进入接单或者制作中状态
     */
    @PostConstruct
    public void autoAccept() {
        log.info("触发已新建进入接单状态启动");
        if (flag) {
            return;
        }
        flag = true;
        CompletableFuture.runAsync(() -> {
            while (flag) {
                try {
                    log.info("自动交卷start");
                    DemoDTO dto = delayQueue.take();
                    if (dto != null) {
                        log.info("自动交卷ing");
                        handPaper(dto);
                    }
                    log.info("自动交卷开始end");
                } catch (Exception e) {
                    log.error("自动交卷异常", e);
                }
            }
        }, ACCEPTED_DELAY_QUEUE_EXECUTOR).exceptionally(throwable -> {
                    log.error("自动交卷异常处理线程异常", throwable);
                    return null;
                }
        );
    }


    /**
     * 交卷
     *
     * @param dto
     */
    private void handPaper(DemoDTO dto) {
        log.info("试卷:{}-010-进入自动交卷{}", dto.getExamNo(), JSON.toJSONString(dto));
            try {
               testService.handInPapers(dto);
            } catch (Exception e) {
                log.error("试卷{}->自动交卷异常", dto.getExamNo(), e);
                exceptionHandle(dto, NumberConstants.NUM_2);
            }
    }


    /**
     * 异常处理，多次异常则抛弃
     *
     * @param dto
     * @param type
     */
    private void exceptionHandle(DemoDTO dto, Integer type) {
        try {
            Integer errorNum = dto.getErrorNum() == null ? NumberConstants.NUM_0 : dto.getErrorNum();
            if (errorNum >= NumberConstants.NUM_3) {
                log.info("试卷{}多次自动交卷异常，抛弃,{}", dto.getExamNo(), JSON.toJSONString(dto));
                return;
            }
            ++errorNum;
            //延迟一会交卷，可能导致交卷顺序有问题，可以忽略
            if (type == NumberConstants.NUM_1) {
                dto.setTestTime(NumberConstants.NUM_100L);
            }
            dto.setErrorNum(errorNum);
            delayQueue.add(dto);
        } catch (Exception e) {
            log.error("订单号{}已接单多次处理异常", dto.getExamNo(), e);
        }
    }


    public static DelayQueue<DemoDTO> getDelayQueue() {
        return delayQueue;
    }


    @PreDestroy
    private void destroy() {
        flag = false;
    }



}
